home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
magazine
/
progjour
/
1989
/
03a
/
display.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1989-02-22
|
5KB
|
255 lines
// display.cpp the Display class methods
//
// (c) Aspen Scientific 1989. All Rights Reserved.
// Author: Vaughn Vernon
#include "display.cls"
// for Microsoft C, not Zortech
#ifndef __ZTC__
# include <memory.h>
# include <conio.h>
#else
static void movedata(unsigned, unsigned, unsigned, unsigned, unsigned);
#endif
// ***************************************************************
// ** the Display methods in this file are implemented for MS-DOS
// ** in a text display (non-graphics) environment. it uses
// ** 8086 interrupts and the Microsoft C int86() function, as
// ** well as far pointers to the video memory map segment.
// ***************************************************************
#include <dos.h>
static union REGS vRegs;
static union REGS videoSaveMode;
static const unsigned monoSeg = 0xb000;
static const unsigned colorSeg = 0xb800;
#if defined(M_I86SM) || defined(M_I86MM)
static unsigned ds;
#endif
static unsigned map[80];
Display::Display(const Mouse * mou) : cursor(0,0)
{
if (init == 1)
return;
mouse = mou;
// for small and medium models (small data), need data seg
struct SREGS segs;
segread(&segs);
ds = segs.ds;
// find out the current video mode, save
// it, then set the new mode if necessary.
vRegs.h.ah = 0x0f;
int86(0x10, &vRegs, &vRegs);
videoSaveMode = vRegs;
// return of 7 in AL register is mono
if (vRegs.h.al == 7) {
videoSeg = monoSeg;
color = 0;
snow = 0;
}
else {
videoSeg = colorSeg;
color = 1;
if (vRegs.h.al != 3) {
vRegs.h.ah = 0;
vRegs.h.al = 3;
int86(0x10, &vRegs, &vRegs);
}
// check for a snowing display; an EGA
// or VGA is automatic no-snow.
unsigned EGAMemory, EGAMode;
vRegs.h.ah = 0x12;
vRegs.h.bl = 0x10;
int86(0x10, &vRegs, &vRegs);
EGAMemory = vRegs.h.bl;
EGAMode = vRegs.h.bh;
// if the returned memory is out of range, or
// the ega/vga card is not attached to the color
// display (EGAMode != 0), assume snow.
if (EGAMemory < 0 || EGAMemory > 3 || EGAMode != 0)
snow = 1;
else
snow = 0;
}
// set the Display size
origin(Point(0,0));
corner(Point(24,79));
clear();
draw();
init=1;
}
Display::~Display()
{
clear();
cursor(0,0);
draw();
vRegs = videoSaveMode;
int86(0x10, &vRegs, &vRegs);
}
void
Display::clear()
{
Point size = extent();
mouse->hide();
vRegs.h.dh = size.x() + 1;
vRegs.h.dl = size.y() + 1;
vRegs.h.bh = defAttr.get() >> 8;
vRegs.x.cx = 0;
vRegs.h.al = 0;
vRegs.h.ah = 6;
int86(0x10, &vRegs, &vRegs);
mouse->show();
}
void
Display::operator()(unsigned row, unsigned col)
{
Point top, bot;
top = origin();
bot = corner();
if (row < top.x() || row > bot.x() ||
col < top.y() || col > bot.y())
return;
// move cursor
cursor(int(row), int(col));
draw();
}
void
Display::cursorOff()
{
vRegs.x.cx = 0x2000;
vRegs.h.ah = 1;
int86(0x10, &vRegs, &vRegs);
}
void
Display::cursorOn()
{
if (hasColor())
vRegs.x.cx = 0x0607;
else
vRegs.x.cx = 0x0b0c;
vRegs.h.ah = 1;
int86(0x10, &vRegs, &vRegs);
}
void
Display::putString(Point & p, const unsigned char * s, DisplayAttr & a)
{
cursor = p;
register unsigned c = cursor.y();
register unsigned len=0;
unsigned *mp = map;
for ( ; c <= width() && *s; ++c, ++len)
*mp++ = (unsigned)*s++ | a.get();
mouse->hide();
// protect against flicker
if (snow)
while ((inp(0x03da) & 8) == 0)
;
#if defined(M_I86SM) || defined(M_I86MM)
movedata(ds, (unsigned)map,
#else
movedata(FP_SEG(map), FP_OFF(map),
#endif
videoSeg, cursor.x() * 160 + cursor.y() * 2, len * 2);
mouse->show();
cursor(cursor.x(), c);
}
void
Display::putChar(Point & p, unsigned char c, DisplayAttr & a)
{
cursor = p;
*map = c | a.get();
mouse->hide();
// protect against flicker
if (snow)
while ((inp(0x03da) & 8) == 0)
;
#if defined(M_I86SM) || defined(M_I86MM)
movedata(ds, (unsigned)map,
#else
movedata(FP_SEG(map), FP_OFF(map),
#endif
videoSeg, cursor.x() * 160 + cursor.y() * 2, 2);
mouse->show();
if (cursor.y() != width())
cursor(cursor.x(), cursor.y() + 1);
}
// just update cursor
void
Display::draw()
{
vRegs.h.dh = cursor.x();
vRegs.h.dl = cursor.y();
vRegs.h.bh = 0;
vRegs.h.ah = 2;
int86(0x10, &vRegs, &vRegs);
}
#ifdef __ZTC__
static void
movedata(unsigned sSeg, unsigned sOff, unsigned dSeg, unsigned dOff, unsigned n)
{
unsigned far *src, far *dest;
src = MK_FP(sSeg, sOff);
dest = MK_FP(dSeg, dOff);
// divide by 2
n >>= 1;
for (register int i=0; i < n; ++i)
*dest++ = *src++;
}
#endif